package com.csun.cmny.provider.service.impl;

import com.csun.cmny.base.enums.ErrorCodeEnum;
import com.csun.cmny.config.properties.CmnyProperties;
import com.csun.cmny.core.support.BaseService;
import com.csun.cmny.provider.dao.DmcCsunSleepDataHiMapper;
import com.csun.cmny.provider.exceptions.DmcBizException;
import com.csun.cmny.provider.model.domain.DmcCsunSleepDataHi;
import com.csun.cmny.provider.model.dto.app.AppSleepDateQueryDto;
import com.csun.cmny.provider.model.dto.csunsleep.CsunSleepDataHiQueryDto;
import com.csun.cmny.provider.model.entity.TimeRange;
import com.csun.cmny.provider.service.DmcCsunSleepDataHiService;
import com.csun.cmny.provider.utils.DateUtil;
import com.csun.cmny.util.PublicUtil;
import com.csun.cmny.util.RedisKeyUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.*;
import java.net.Socket;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * @Auther: chisj chisj@foxmal.com
 * @Date: 2019-02-15 11:02
 * @Description: the class dmc csun sleep data hi service impl
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class DmcCsunSleepDataHiServiceImpl extends BaseService<DmcCsunSleepDataHi>
        implements DmcCsunSleepDataHiService {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private DmcCsunSleepDataHiMapper dmcCsunSleepDataHiMapper;

    @Resource
    private CmnyProperties cmnyProperties;

    @Resource
    private DmcCsunSleepDataHiService dmcCsunSleepDataHiService;

    /**
     * query csun sleep hi data list with page
     *
     * @param csunSleepDataHiQueryDto csun sleep data hi query dto
     * @return the page info.
     */
    @Override
    public String queryCsunSleepHiDataListWithPage(CsunSleepDataHiQueryDto csunSleepDataHiQueryDto) {

        Date start = new Date();

        PageHelper.startPage(csunSleepDataHiQueryDto.getPageNum(), csunSleepDataHiQueryDto.getPageSize());

        // order by asc
        List<DmcCsunSleepDataHi> dmcCsunSleepDataHiList = dmcCsunSleepDataHiMapper
                .queryCsunSleepHiDataListWithPage(csunSleepDataHiQueryDto);

        if (PublicUtil.isEmpty(dmcCsunSleepDataHiList) || dmcCsunSleepDataHiList.size() < 2) {
            throw new DmcBizException(ErrorCodeEnum.DMC100610057);
        }

        Date end = new Date();
        log.info("query csun sleep hi data time = {}", end.getTime() - start.getTime());

        start = new Date();
        List<Integer> inBedList = Lists.newArrayList();
        List<Integer> heartbeatList = Lists.newArrayList();
        List<Integer> breathList = Lists.newArrayList();
        List<Long> createdTimeList = Lists.newArrayList();
        List<String> statusList = Lists.newArrayList();
        List<Integer> actionList = Lists.newArrayList();
        List<Long> actionTimeList = Lists.newArrayList();
        long startTime = 0l;
        long endTime = 0l;
        for (DmcCsunSleepDataHi data : dmcCsunSleepDataHiList) {
            long time = data.getCreatedTime().getTime() / 1000;
            inBedList.add(data.getInBed());
            heartbeatList.add(data.getHeartbeat());
            breathList.add(data.getBreath());
            createdTimeList.add(time);
            statusList.add(data.getStatus());
            actionList.add(data.getAction());
            if (PublicUtil.isNotEmpty(data.getActionTime())) {
                actionTimeList.add(data.getActionTime().getTime() / 1000);
            } else {
                actionTimeList.add(null);
            }
            endTime = time;
        }

        Map<String, Object> map = Maps.newHashMap();
        map.put("inBed", inBedList);
        map.put("heartbeat", heartbeatList);
        map.put("breath", breathList);
        map.put("createdTime", createdTimeList);
        map.put("status", statusList);
        map.put("action", actionList);
        map.put("actionTime", actionTimeList);
        startTime = dmcCsunSleepDataHiList.get(0).getCreatedTime().getTime() / 1000;
        map.put("start", startTime);
        map.put("end", endTime);
        log.info("=====> step = {}", csunSleepDataHiQueryDto.getStep());
        map.put("step", csunSleepDataHiQueryDto.getStep());
        map.put("smoothFactor", csunSleepDataHiQueryDto.getSmoothFactor());

        String jsonStr = JSONObject.fromObject(map).toString();
        log.info("jsonStr ==> {}", jsonStr);

        /**
         * 采集数据 - 将入参写入文件
         */
//        String filePathPrefix = "G:\\python\\";
//        String date_prefix = DateUtil.dateToStrings(new Date());
//        String in_filePath = filePathPrefix + date_prefix + "input.json";
//        String out_filePath = filePathPrefix + date_prefix + "out.json";
//        File in_file = new File(in_filePath);
//        File out_file = new File(out_filePath);

//        try {
//            PrintStream ps = new PrintStream(new FileOutputStream(in_file));
//            ps.println(jsonStr);
//            ps.close();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }

        //String jsonStr = JSONArray.fromObject(dmcCsunSleepDataHiList).toString();
//        String filePathPrefix = "G:\\python\\";
//        String filePathPrefixRedis = (String) redisTemplate.opsForValue().get(RedisKeyUtil.getCsunSleepDataFilePrefix());
//        if (PublicUtil.isNotEmpty(filePathPrefix)) {
//            filePathPrefix = filePathPrefixRedis;
//        }
//        String date_prefix = DateUtil.dateToStrings(new Date());
//        String filePath = filePathPrefix + date_prefix + "input.json";
//        log.info("============> filePath: {}", filePath);
//        File file = new File(filePath);
//        try {
//            PrintStream ps = new PrintStream(new FileOutputStream(file));
//            ps.println(jsonStr);
//            ps.close();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//
//        end = new Date();
//        log.info("save csun sleep hi data time = {}", end.getTime() - start.getTime());

        start = new Date();

        String outputJson = "";
        try {

            Socket socket = new Socket(cmnyProperties.getPython().getAddress(),
                    cmnyProperties.getPython().getPort());
            if (!socket.isConnected()) {
                log.error("python server connect error.");
                return null;
            }

            // 阻塞 1000ms
            socket.setSoTimeout(cmnyProperties.getPython().getTimeout());

            BufferedWriter write = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));     //可用PrintWriter
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            String hello = in.readLine();
            log.info("hello: {}", hello);
            if (!hello.equals("Hello")) {
                return null;
            }

            write.write(jsonStr + "CSUN");
            write.flush();

            outputJson = in.readLine();
            log.info("outputJson: {}", outputJson);

            write.close();
            in.close();
            socket.close();
        } catch (Exception e) {
            log.error("get output json error: {}", e.getMessage());
        }


//        String exec = "python";
//        String command = filePathPrefix + "python_csun.py";
//        String result = filePathPrefix + date_prefix + "output.json";
//        String cmdArr[] = new String[]{exec, command, filePath};
//        try {
//            Process pr = Runtime.getRuntime().exec(cmdArr);
//            BufferedReader in = new BufferedReader(new InputStreamReader(
//                    pr.getInputStream()));
//            in.close();
//            pr.waitFor();
//        } catch (Exception e) {
//            log.error("python exec error: {}", e.getMessage());
//        }
//
//        end = new Date();
//        log.info("python csun sleep hi data time = {}", end.getTime() - start.getTime());
//
//        start = new Date();
//        String resultJson = "";
//        // 读取文件
//        try {
//            StringBuilder sb = new StringBuilder();
//            String line;
//            FileReader fileReader = new FileReader(result);
//            BufferedReader bufferedReader = new BufferedReader(fileReader);
//            while ((line = bufferedReader.readLine()) != null) {
//                // 一次读入一行数据
//                sb.append(line);
//            }
//            resultJson = sb.toString();
//        } catch (Exception e) {
//            log.error("file reader error: {}", e.getMessage());
//        }

//        try {
//            PrintStream out_ps = new PrintStream(new FileOutputStream(out_file));
//            out_ps.println(outputJson);
//            out_ps.close();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }

        end = new Date();
        log.info("read csun sleep hi data time = {}", end.getTime() - start.getTime());
        //return new PageInfo<>(dmcCsunSleepDataHiList);
        return outputJson;
    }

    @Override
    public List<DmcCsunSleepDataHi> selectDataByDate(Long deviceId, Date startTime, Date endTime) {

        CsunSleepDataHiQueryDto hiQuery = new CsunSleepDataHiQueryDto();
        hiQuery.setDeviceId(deviceId);
        hiQuery.setStartQueryTime(startTime);
        hiQuery.setEndQueryTime(endTime);
        return dmcCsunSleepDataHiMapper.queryCsunSleepHiDataListWithPage(hiQuery);
    }

    @Override
    public List<TimeRange> getSingleDayInBedTimeRangeList(CsunSleepDataHiQueryDto csunSleepDataHiQueryDto) {

        //根据起止时间 设备Id查询设备数据
        csunSleepDataHiQueryDto.setPageSize(65535);
        List<DmcCsunSleepDataHi> hiList = dmcCsunSleepDataHiService.selectDataByDate(csunSleepDataHiQueryDto.getDeviceId(),csunSleepDataHiQueryDto.getStartQueryTime(),csunSleepDataHiQueryDto.getEndQueryTime());

        //在床时间段
        List<TimeRange> inBedTimeRangeList = new LinkedList<>();

        //获取在床时间段集合
        for(int i = 0,j = hiList.size() ; i < j ; i++){
            if(hiList.get(i).getInBed() == 1){
                for(int k = i ; k<j ; k++){
                    if(hiList.get(k+1).getInBed() == 0){
                        TimeRange inBedTimeRange = new TimeRange();
                        inBedTimeRange.setStartTime(hiList.get(i).getCreatedTime());
                        inBedTimeRange.setEndTime(hiList.get(k).getCreatedTime());
                        inBedTimeRangeList.add(inBedTimeRange);
                    }
                    i = k++;
                }
            }
        }
        return inBedTimeRangeList;
    }

    @Override
    public Integer countOfflineTimes(AppSleepDateQueryDto appSleepDateQueryDto) {
        return dmcCsunSleepDataHiMapper.countOfflineTimes(appSleepDateQueryDto);
    }

    @Override
    public Integer countBreathAlertTimes(AppSleepDateQueryDto appSleepDateQueryDto) {
        return dmcCsunSleepDataHiMapper.countBreathAlertTimes(appSleepDateQueryDto);
    }

    @Override
    public Integer countHeartbeatAlertTimes(AppSleepDateQueryDto appSleepDateQueryDto) {
        return dmcCsunSleepDataHiMapper.countHeartbeatAlertTimes(appSleepDateQueryDto);
    }
}
